package org.loofer.uikit;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.util.AttributeSet;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.widget.ImageView;

public class ExtendImageView extends ImageView {
    private static final ThreadLocal<Rect> sLocalTmpRect = new ThreadLocal<Rect>() {
        protected Rect initialValue() {
            return new Rect();
        }
    };
    private boolean mAdjustViewBounds = false;
    private boolean mBlockMeasurement = false;
    private ViewForeground mForeground = new ViewForeground((View) this, null);
    private int mForegroundResource = 0;
    private boolean mIgnoreContentBounds = false;
    private boolean mMeasuredExactly = false;

    public ExtendImageView(Context context) {
        super(context);
    }

    public ExtendImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ExtendImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public void setImageBitmap(Bitmap bm) {
        setImageBitmapInternal(bm);
    }

    private void setImageBitmapInternal(Bitmap bm) {
        this.mBlockMeasurement = true;
        super.setImageBitmap(bm);
        this.mBlockMeasurement = false;
    }

    public void setImageDrawable(Drawable drawable) {
        setImageDrawableInternal(drawable);
    }

    private void setImageDrawableInternal(Drawable drawable) {
        this.mBlockMeasurement = true;
        super.setImageDrawable(drawable);
        this.mBlockMeasurement = false;
    }

    public void setImageResource(int resId) {
        setImageResourceInternal(resId);
    }

    private void setImageResourceInternal(int resId) {
        this.mBlockMeasurement = true;
        super.setImageResource(resId);
        this.mBlockMeasurement = false;
    }

    public void setImageURI(Uri uri) {
        setImageURIInternal(uri);
    }

    private void setImageURIInternal(Uri uri) {
        this.mBlockMeasurement = true;
        super.setImageURI(uri);
        this.mBlockMeasurement = false;
    }

    public void setImageBitmap(Bitmap bm, Animation in, Animation out) {
        if (out != null) {
            final Bitmap fbm = bm;
            final Animation fin = in;
            scheduleAnimation(out, new Runnable() {
                public void run() {
                    ExtendImageView.this.setImageBitmapInternal(fbm);
                    if (fin != null) {
                        ExtendImageView.this.scheduleAnimation(fin, null);
                    }
                }
            });
            return;
        }
        setImageBitmapInternal(bm);
        if (in != null) {
            scheduleAnimation(in, null);
        }
    }

    public void setImageDrawable(Drawable drawable, Animation in, Animation out) {
        if (out != null) {
            final Drawable fdrawable = drawable;
            final Animation fin = in;
            scheduleAnimation(out, new Runnable() {
                public void run() {
                    ExtendImageView.this.setImageDrawableInternal(fdrawable);
                    if (fin != null) {
                        ExtendImageView.this.scheduleAnimation(fin, null);
                    }
                }
            });
            return;
        }
        setImageDrawableInternal(drawable);
        if (in != null) {
            scheduleAnimation(in, null);
        }
    }

    public void setImageResource(int resId, Animation in, Animation out) {
        if (out != null) {
            final int fresid = resId;
            final Animation fin = in;
            scheduleAnimation(out, new Runnable() {
                public void run() {
                    ExtendImageView.this.setImageResourceInternal(fresid);
                    if (fin != null) {
                        ExtendImageView.this.scheduleAnimation(fin, null);
                    }
                }
            });
            return;
        }
        setImageResourceInternal(resId);
        if (in != null) {
            scheduleAnimation(in, null);
        }
    }

    public void setImageURI(Uri uri, Animation in, Animation out) {
        if (out != null) {
            final Uri furi = uri;
            final Animation fin = in;
            scheduleAnimation(out, new Runnable() {
                public void run() {
                    ExtendImageView.this.setImageURIInternal(furi);
                    if (fin != null) {
                        ExtendImageView.this.scheduleAnimation(fin, null);
                    }
                }
            });
            return;
        }
        setImageURIInternal(uri);
        if (in != null) {
            scheduleAnimation(in, null);
        }
    }

    public void setBackgroundDrawable(Drawable drawable) {
        boolean z;
        if (isBackgroundHasPadding(getBackground(), drawable)) {
            z = false;
        } else {
            z = true;
        }
        this.mBlockMeasurement = z;
        super.setBackgroundDrawable(drawable);
        this.mBlockMeasurement = false;
    }

    public void setBackgroundResource(int resId) {
        this.mBlockMeasurement = true;
        super.setBackgroundResource(resId);
        this.mBlockMeasurement = false;
    }

    public void setBackgroundColor(int color) {
        this.mBlockMeasurement = true;
        super.setBackgroundColor(color);
        this.mBlockMeasurement = false;
    }

    private boolean isBackgroundHasPadding(Drawable oldDrawable, Drawable newDrawable) {
        boolean hasPadding;
        Rect rect = (Rect) sLocalTmpRect.get();
        if (oldDrawable == null || !oldDrawable.getPadding(rect)) {
            hasPadding = false;
        } else {
            hasPadding = true;
        }
        if (hasPadding) {
            return hasPadding;
        }
        if (newDrawable == null || !newDrawable.getPadding(rect)) {
            return false;
        }
        return true;
    }

    public void requestLayout() {
        if (!this.mBlockMeasurement || !this.mMeasuredExactly) {
            super.requestLayout();
        }
    }

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        this.mMeasuredExactly = isMeasuredExactly(widthMeasureSpec, heightMeasureSpec);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (this.mIgnoreContentBounds && !this.mAdjustViewBounds) {
            setMeasuredDimension(getDefaultSize(getMeasuredWidth(), widthMeasureSpec), getDefaultSize(getMeasuredHeight(), heightMeasureSpec));
        }
    }

    private boolean isMeasuredExactly(int widthMeasureSpec, int heightMeasureSpec) {
        return MeasureSpec.getMode(widthMeasureSpec) == 1073741824 && MeasureSpec.getMode(heightMeasureSpec) == 1073741824;
    }

    public void setForeground(int resId) {
        if (resId == 0 || resId != this.mForegroundResource) {
            this.mForegroundResource = resId;
            setForegroundInternal(resId != 0 ? getResources().getDrawable(resId) : null);
        }
    }

    public void setForeground(Drawable foregroundDrawable) {
        if (foregroundDrawable != this.mForeground.getDrawable()) {
            this.mForegroundResource = 0;
            setForegroundInternal(foregroundDrawable);
        }
    }

    private void setForegroundInternal(Drawable drawable) {
        this.mBlockMeasurement = true;
        this.mForeground.setDrawable(drawable);
        this.mBlockMeasurement = false;
    }

    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        ViewForeground foreground = this.mForeground;
        if (foreground != null) {
            foreground.dispatchBoundsChanged();
        }
    }

    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        ViewForeground foreground = this.mForeground;
        if (foreground != null) {
            foreground.dispatchBoundsChanged();
        }
    }

    protected void drawableStateChanged() {
        super.drawableStateChanged();
        ViewForeground foreground = this.mForeground;
        if (foreground != null) {
            foreground.dispatchDrawableStateChanged();
        }
    }

    protected boolean verifyDrawable(Drawable dr) {
        ViewForeground foreground = this.mForeground;
        return (foreground == null ? null : foreground.getDrawable()) == dr || super.verifyDrawable(dr);
    }

    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        ViewForeground foreground = this.mForeground;
        if (foreground != null) {
            foreground.dispatchDraw(canvas);
        }
    }

    public void setAdjustViewBounds(boolean adjustViewBounds) {
        super.setAdjustViewBounds(adjustViewBounds);
        this.mAdjustViewBounds = adjustViewBounds;
    }

    public boolean getAdjustViewBounds() {
        return this.mAdjustViewBounds;
    }

    public void setIgnoreContentBounds(boolean ignore) {
        if (this.mIgnoreContentBounds != ignore) {
            this.mIgnoreContentBounds = ignore;
            requestLayout();
        }
    }

    private void scheduleAnimation(Animation animation, final Runnable postRunnable) {
        if (animation != null) {
            clearAnimation();
            animation.setAnimationListener(new AnimationListener() {
                public void onAnimationStart(Animation animation) {
                }

                public void onAnimationEnd(Animation animation) {
                    if (postRunnable != null) {
                        postRunnable.run();
                    }
                }

                public void onAnimationRepeat(Animation animation) {
                }
            });
            startAnimation(animation);
        } else if (postRunnable != null) {
            postRunnable.run();
        }
    }
}
